package com.accenture.automation.common;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;


/**************************************************************
 * <br>
 * 文件操作 <br>bbz
 **************************************************************/
public class FileUtil {

    public static final String PATTERN_TIME = "{TIME}";
    public static final String PATTERN_TIME2 = "\\{TIME\\}";

    public static final String SERIALNO = ".*";

    public static final int[] TIMEARRAY = {0, 1, 2, 3, 4, 5};

    public static final String SECONDPATTERN = "[0-5][0-9]";

    /**
     * 文件是否存在
     * 
     * @param filePath
     *            - 文件绝对路径
     * @return - 存在true，不存在false
     */
    public static boolean isExists(String filePath) {
        File file = new File(filePath);
        return file.exists();
    }

    /**
     * 是否是文件，用来判断是文件还是文件夹
     * 
     * @param filePath
     *            - 文件绝对路径
     * @return - 文件true，否则false
     */
    public static boolean isFile(String filePath) {
        File file = new File(filePath);
        return file.isFile();
    }

    /**
     * 是否是文件夹，用来判断是文件还是文件夹
     * 
     * @param filePath
     *            - 文件绝对路径
     * @return - 文件夹true，否则false
     */
    public static boolean isDir(String filePath) {
        File file = new File(filePath);
        return file.isDirectory();
    }

    /**
     * 创建新文件
     * 
     * @param filePath
     *            路径
     * @param fileName
     *            文件名称
     * @return true 成功 false 失败
     */
    public static boolean creatFile(String filePath, String fileName) {
        File creatFile = new File(filePath + File.separator + fileName);
        try {
            if (creatFile.createNewFile()) {
                return true;
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return false;
    }

    /**
     * 创建新目录
     * 
     * @param filePath
     *            路径
     * @param dirName
     *            目录文件名称
     * @return true 成功 false 失败
     */
    public static boolean creatdir(String filePath, String dirName) {
        File creatDir = new File(filePath + File.separator + dirName);

        if (creatDir == null || !creatDir.isDirectory()) {
            if (creatDir.mkdirs()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 创建新目录
     * 
     * @param filePath
     *            路径
     * @return true 成功 false 失败
     */
    public static boolean creatdir(String filePath) {
        File creatDir = new File(filePath);

        if (creatDir != null) {
            if (creatDir.mkdirs()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 拷贝文件
     * 
     * @param sourcePath
     *            源文件路径
     * @param fileName
     *            文件名称
     * @param targetPath
     *            目标文件路径
     * @return 是否拷贝成功
     */
    public static boolean copyFile(String sourcePath, String fileName,
            String targetPath) {
        return copyFile(sourcePath, fileName, targetPath, fileName);
    }

    /**
     * 拷贝文件
     * 
     * @param sourcePath
     *            源文件路径
     * @param fileName
     *            文件名称
     * @param targetPath
     *            目标文件路径
     * @param targetFileName
     *            目标文件名
     * @return 是否拷贝成功
     */
    @SuppressWarnings("resource")
	public static boolean copyFile(String sourcePath, String fileName,
            String targetPath, String targetFileName) {
        boolean flag = false;
        File sourceFile = new File(sourcePath + File.separator + fileName);
        long lastModifyTime = sourceFile.lastModified();
        FileChannel in = null;
        FileChannel out = null;
        try {
            // 源文件输入流
            in = new FileInputStream(sourceFile).getChannel();
            // 目标文件对象
            File targetFile = new File(targetPath, targetFileName);
            // 目标文件输出流
            out = new FileOutputStream(targetFile).getChannel();
            // 读写缓存
            ByteBuffer buffer = ByteBuffer.allocate(1024);

            while (true) {
                buffer.clear();
                int r = in.read(buffer);
                if (r == -1) {
                    break;
                }
                buffer.flip();
                out.write(buffer);
            }
            out.close();
            in.close();
            
            targetFile.setLastModified(lastModifyTime);
            
            flag = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (in != null && in.isOpen()) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (out != null && out.isOpen()) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return flag;
    }

    /**
     * 剪切文件
     * 
     * @param sourcePath
     *            源文件路径
     * @param fileName
     *            文件名称
     * @param targetPath
     *            目标文件路径
     * @return 是否移动成功
     */
    public static boolean moveFile(String sourcePath, String fileName,
            String targetPath) {
        boolean flag = false;
        File sourceFile = new File(sourcePath + File.separator + fileName);
        File destFile = new File(targetPath + File.separator + fileName);
        // 使用renameTo搬移文件
        flag = sourceFile.renameTo(destFile);
        if (!flag) {
            // 如果renameTo失败，使用流进行搬移
            flag = copyFile(sourcePath, fileName, targetPath);
            if (flag) {
                flag = sourceFile.delete();
            }
        }
        return flag;
    }

    /**
     * 剪切文件
     * 
     * @param sourcePath
     *            源文件路径
     * @param fileName
     *            文件名称
     * @param targetPath
     *            目标文件路径
     * @param targetFileName
     *            目标文件名
     * @return 是否移动成功
     */
    public static boolean moveFile(String sourcePath, String fileName,
            String targetPath, String targetFileName) {
        boolean flag = false;
        File sourceFile = new File(sourcePath + File.separator + fileName);
        File destFile = new File(targetPath + File.separator + targetFileName);
        flag = sourceFile.renameTo(destFile);
        if (!flag) {
            flag = copyFile(sourcePath, fileName, targetPath,
                    targetFileName);
            if (flag) {
                // File sourceFile = new File(sourcePath + File.separator +
                // fileName);
                flag = sourceFile.delete();
            }
        }
        return flag;
    }

    /**
     * 删除文件
     * 
     * @param filePath
     *            路径
     * @param fileName
     *            文件名称
     * @return true
     */
    public static boolean deleteFile(String filePath, String fileName) {
        File deleteFile = new File(filePath + File.separator + fileName);
        if (!deleteFile.exists()) {
            return true;
        }
        if (!deleteFile.delete()) {
            return false;
        }
        return true;
    }

    /**
     * 清空目录下文件
     * 
     * @param filePath
     *            目录路径
     * @return clearResult true 成功 false失败
     */
    public static boolean clearDirFile(String filePath) {
        boolean clearResult = true;
        File fileDie = new File(filePath);
        File[] files = fileDie.listFiles();
        for (File fileTmp : files) {
            if (!deleteDir(fileTmp)) {
                clearResult = false;
                break;
            }
        }
        return clearResult;
    }

    /**
     * 删除目录
     * 
     * @param fileDir
     *            目录对象
     * @return true 成功 false失败
     */
    public static boolean deleteDir(File fileDir) {
        if (!fileDir.exists()) {
            return true;
        }
        if (!fileDir.isDirectory()) {
            if (!fileDir.delete()) {
                return false;
            }
            return true;
        }
        File[] files = fileDir.listFiles();
        for (File fileTmp : files) {
            deleteDir(fileTmp);
        }
        if (fileDir.listFiles().length == 0) {
            if (!fileDir.delete()) {
                return false;
            }
        }
        return true;
    }

    /**
     * 获取目录下所有文件列表数组
     * 
     * @param filePath
     *            - 文件路径
     * @return - 文件列表数组
     */
    public static String[] files(String filePath) {
        String[] files = null;
        if (isDir(filePath)) {
            File fileDir = new File(filePath);
            files = fileDir.list();
        }
        return files;
    }

    /**
     * 根据文件名正则表达式获取某路径下文件列表
     * 
     * @param filePath
     *            - 文件路径
     * @param regex
     *            - 文件名正则表达式
     * @return - 文件数组
     */
    public static File[] files(String filePath, final String regex) {
        String filePathTmp = StringUtil.checkEndWith(filePath, File.separator);
        File[] files = null;
        if (isDir(filePathTmp)) {
            File fileDir = new File(filePathTmp);
            files = fileDir.listFiles(new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.matches(regex);
                }
            });
        }

        return files;
    }

    /**
     * 判断文件名称是否符合正则判断
     * 
     * @param name
     *            - 文件名称
     * @param regulaExpress
     *            - 正则表达式
     * @return - 是true，否false
     */
    public static boolean isPatternFile(String name, String regulaExpress) {
        boolean result = false;
        result = name.matches(regulaExpress);
        return result;
    }

    /**
     * 检查父目录
     * 如父目录不存在时，创建父目录。
     * 
     * @param dirFile
     *            当前操作文件对象
     */
    public static void parentDirCheck(File dirFile) {

        File parentFile = dirFile.getParentFile();
        // 父目录是否存在
        if (!parentFile.exists()) {

            // 递归寻找上级目录
            parentDirCheck(parentFile);

            parentFile.mkdir();
        }

    }
}
